package com.geezdata.cps.sdk3rd.pinduoduo;

import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Objects;
import java.util.TreeMap;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.geezdata.cps.base.enums.ErrorCode;
import com.geezdata.cps.base.exceptions.MyException;
import com.geezdata.cps.base.response.BaseResponse;
import com.geezdata.cps.base.utils.EmojiUtil;
import com.geezdata.cps.base.utils.HttpClientUtil;
import com.geezdata.cps.base.utils.Md5Util;
import com.geezdata.cps.sdk3rd.common.domain.BaseOrder;
import com.geezdata.cps.sdk3rd.common.response.BaseOrderListResult;
import com.geezdata.cps.sdk3rd.pinduoduo.constant.Constants;
import com.geezdata.cps.sdk3rd.pinduoduo.domain.PinduoduoGoodsListGet;
import com.geezdata.cps.sdk3rd.pinduoduo.domain.PinduoduoLogisticsCompanies;
import com.geezdata.cps.sdk3rd.pinduoduo.domain.PinduoduoTrade;
import com.geezdata.cps.sdk3rd.pinduoduo.request.PinduoduoAccessTokenRequest;
import com.geezdata.cps.sdk3rd.pinduoduo.request.PinduoduoDDKGoodsDeatilRequest;
import com.geezdata.cps.sdk3rd.pinduoduo.request.PinduoduoDDKGoodsPIdRequest;
import com.geezdata.cps.sdk3rd.pinduoduo.request.PinduoduoDDKGoodsPromotionUrlRequest;
import com.geezdata.cps.sdk3rd.pinduoduo.request.PinduoduoDDKGoodsRequest;
import com.geezdata.cps.sdk3rd.pinduoduo.request.PinduoduoDDKMallUrlGenRequest;
import com.geezdata.cps.sdk3rd.pinduoduo.request.PinduoduoDDKOrderListIncrementRequest;
import com.geezdata.cps.sdk3rd.pinduoduo.request.PinduoduoDDKthemeGoodsSearchRequest;
import com.geezdata.cps.sdk3rd.pinduoduo.request.PinduoduoGoodsListGetRequest;
import com.geezdata.cps.sdk3rd.pinduoduo.request.PinduoduoGoodsOptGetRequest;
import com.geezdata.cps.sdk3rd.pinduoduo.request.PinduoduoLogisticsCompaniesRequest;
import com.geezdata.cps.sdk3rd.pinduoduo.request.PinduoduoOrderIncrementRequest;
import com.geezdata.cps.sdk3rd.pinduoduo.request.PinduoduoOrderInfoRequest;
import com.geezdata.cps.sdk3rd.pinduoduo.request.PinduoduoRefreshAccessTokenRequest;
import com.geezdata.cps.sdk3rd.pinduoduo.response.PinduoduoAccessTokenResult;
import com.geezdata.cps.sdk3rd.pinduoduo.response.PinduoduoDDKGoodsDetailResult;
import com.geezdata.cps.sdk3rd.pinduoduo.response.PinduoduoDDKGoodsPidGenerateResult;
import com.geezdata.cps.sdk3rd.pinduoduo.response.PinduoduoDDKGoodsPromotionUrlResult;
import com.geezdata.cps.sdk3rd.pinduoduo.response.PinduoduoDDKGoodsResult;
import com.geezdata.cps.sdk3rd.pinduoduo.response.PinduoduoDDKMallUrlGenResult;
import com.geezdata.cps.sdk3rd.pinduoduo.response.PinduoduoDDKOrderListIncrementResult;
import com.geezdata.cps.sdk3rd.pinduoduo.response.PinduoduoDDKThemeGoodsSearchResult;
import com.geezdata.cps.sdk3rd.pinduoduo.response.PinduoduoGoodsListGetResult;
import com.geezdata.cps.sdk3rd.pinduoduo.response.PinduoduoGoodsOptGetResult;
import com.geezdata.cps.sdk3rd.pinduoduo.response.PinduoduoLogisticsCompaniesResult;
import com.geezdata.cps.sdk3rd.pinduoduo.response.PinduoduoOrderIncrementResult;
import com.geezdata.cps.sdk3rd.pinduoduo.response.PinduoduoOrderInfoResult;


public class PinduoduoDefaultClient implements PinduoduoClient{
	private static final Logger logger = LoggerFactory.getLogger(PinduoduoDefaultClient.class);
	private static final long DEFAULT_SLEEP_TIME_TO_GET_ORDER = 50;
	private static final int DEFAULT_TRY_TIMES = 3;

	private static final String SHOP_NAME_BEGIN_URL = "http://apiv3.yangkeduo.com/mall/" ;
	private static final String SHOP_NAME_END_URL = "/info";


    public PinduoduoLogisticsCompaniesResult getLogisticsInfo(PinduoduoLogisticsCompaniesRequest request){
    	// 1、检查serverUrl、appkey、appsert参数是否有空
        if(request == null || StringUtils.isEmpty(Constants.PINDUODUO_API_URL)) {
        	return null;
        }

        String type = request.getMethodName();

    	// 5、生成请求参数
        TreeMap<String, Object> requestParamsMap = new TreeMap<String, Object>();
        requestParamsMap.put("type", type);

    	// 6、发送报文并获取响应的报文串
        String respJson = null;
        try {
            respJson = HttpClientUtil.post(Constants.PINDUODUO_API_URL, requestParamsMap);
        } catch (Exception e) {
            logger.error("Http Post is failed",e);
            return null;
        }
        if(StringUtils.isEmpty(respJson)){
            logger.error("resp Json is empty");
            return null;
        }
        if(JSONObject.parseObject(respJson).containsKey("error_response")){
        	logger.error("resp Json has error:"+JSONObject.parseObject(respJson).toString());
            return null;
        }

        JSONArray logisticsCompanies = JSONObject.parseObject(respJson).getJSONObject("logistics_companies_get_response").getJSONArray("logistics_companies");
        List<PinduoduoLogisticsCompanies> list = logisticsCompanies.toJavaList(PinduoduoLogisticsCompanies.class);

        PinduoduoLogisticsCompaniesResult result = new PinduoduoLogisticsCompaniesResult();
        result.setList(list);
        return result;
    }

    public <T extends BaseOrder> BaseResponse<BaseOrderListResult<T>> execute(PinduoduoOrderIncrementRequest request) {
    	if(Constants.PINDUODUO_AUTH_TYPE_OAUTH.equals(request.getAuthType())) {
            if(request == null || StringUtils.isEmpty(request.getClientId()) ||
            		 StringUtils.isEmpty(request.getClientSecret()) ||
            		 StringUtils.isEmpty(request.getSessionKey()) ) {
            	return BaseResponse.error(ErrorCode.INVALID_PARAMS.getCode(),ErrorCode.INVALID_PARAMS.getDesc());
            }
    	} else if(Constants.PINDUODUO_AUTH_TYPE_USERPWD.equals(request.getAuthType())) {
    		if(request == null ||
           		 StringUtils.isEmpty(request.getPlatformMerchantId()) ||
           		 StringUtils.isEmpty(request.getSessionKey()) ) {
           	return BaseResponse.error(ErrorCode.INVALID_PARAMS.getCode(),ErrorCode.INVALID_PARAMS.getDesc());
           }
    	} else {
    		return BaseResponse.error(ErrorCode.INVALID_PARAMS.getCode(),ErrorCode.INVALID_PARAMS.getDesc());
    	}

        // 检查appParams
        Map<String,Object> paramsMap = request.getAppParams();
        if( paramsMap == null ||  paramsMap.isEmpty() ){
        	return BaseResponse.error(ErrorCode.INVALID_PARAMS.getCode(),ErrorCode.INVALID_PARAMS.getDesc());
        }

        Map<String, Object> requestParamsMap = buildRequestParamsMap(request);

        // 6、发送报文并获取响应的报文串
        String respJson = null;
        try {
        	for(int i=0;i<DEFAULT_TRY_TIMES;i++) {
        		respJson = HttpClientUtil.post(Constants.PINDUODUO_API_URL, requestParamsMap);
        		if(StringUtils.isNotEmpty(respJson)){
        			respJson = EmojiUtil.replaceEmoji(respJson);
        			JSONObject jsonObject = JSONObject.parseObject(respJson);
        			if(jsonObject.containsKey("error_response")) {
        				Integer errorCode = JSONObject.parseObject(respJson).getJSONObject("error_response").getInteger("error_code");
        				if(errorCode == 20021 || errorCode == 70031) {
        					Thread.sleep(DEFAULT_SLEEP_TIME_TO_GET_ORDER);
        				}else {
        					break;
        				}
            		}else {
            			break;
            		}
        		}else {
        			Thread.sleep(DEFAULT_SLEEP_TIME_TO_GET_ORDER);
        		}
        	}

        } catch (Exception e) {
            logger.error("Http Post is failed",e);
            return BaseResponse.error(ErrorCode.HTTP_EXCEPTION.getCode(), e.getMessage());
        }

        if(StringUtils.isEmpty(respJson)){
            logger.error("resp Json is empty");
            return BaseResponse.error(ErrorCode.HTTP_EXCEPTION.getCode(), "resp Json is empty");
        }

        //对返回结果进行error_response的判断
        if(JSONObject.parseObject(respJson).containsKey("error_response")){
        	logger.error("respJson has error:"+JSONObject.parseObject(respJson).toString());
        	Integer errorCode = JSONObject.parseObject(respJson).getJSONObject("error_response").getInteger("error_code");
        	if(errorCode.equals(10014)) {
        		return BaseResponse.error(ErrorCode.HTTP_EXCEPTION.getCode(), Constants.PINDUODUOD_TOKEN_EXPIRED);
        	}
        	if(errorCode.equals(20000) || errorCode.equals(20004) || errorCode.equals(1000000) || errorCode.equals(10014) || errorCode.equals(10019)) {
        		return BaseResponse.error(ErrorCode.HTTP_EXCEPTION.getCode(), Constants.PINDUODUOD_TOKEN_EXPIRED);
        	}
            return BaseResponse.error(ErrorCode.HTTP_EXCEPTION.getCode(), "resp has error_response");
        }

        JSONObject jsonObject = JSONObject.parseObject(respJson);
        @SuppressWarnings("unchecked")
		BaseOrderListResult<T> pinduoduoResult = (BaseOrderListResult<T>) JSONObject.toJavaObject(
        		jsonObject.getJSONObject("order_sn_increment_get_response"), PinduoduoOrderIncrementResult.class);

		return BaseResponse.success(pinduoduoResult);
    }

	private Map<String, Object> buildRequestParamsMap(PinduoduoOrderIncrementRequest request) {
		String mallId = request.getPlatformMerchantId();
	    String clientId = request.getClientId();
	    String type = request.getMethodName();
	    String dataType = "JSON";
	    long timestamp = System.currentTimeMillis() /1000;

	      // 5、生成请求参数
	    TreeMap<String, Object> requestParamsMap = new TreeMap<String, Object>();

	    requestParamsMap.put("type", type);
	    requestParamsMap.put("timestamp", Long.toString(timestamp));
	    requestParamsMap.put("data_type", dataType);

	    for(Entry<String, Object> paramEntry : request.getAppParams().entrySet()){
	    	requestParamsMap.put(paramEntry.getKey(), paramEntry.getValue());
	    }
	    String secret = null;
	    if(Constants.PINDUODUO_AUTH_TYPE_OAUTH.equals(request.getAuthType())) {
	    	secret = request.getClientSecret();
			requestParamsMap.put("client_id", clientId);
			requestParamsMap.put("access_token", request.getSessionKey());
		} else if(Constants.PINDUODUO_AUTH_TYPE_USERPWD.equals(request.getAuthType())) {
			secret = request.getSessionKey();
			requestParamsMap.put("mall_id", mallId);
		}
	    StringBuilder initSign = new StringBuilder(secret);
	    for(Entry<String,Object> param : requestParamsMap.entrySet()){
	    	initSign.append(param.getKey()+param.getValue());
	    }
	    initSign.append(secret);
	    String sign = Md5Util.md5(initSign.toString()).toUpperCase();
	    requestParamsMap.put("sign", sign);
		return requestParamsMap;
	}

	@Override
	public BaseResponse<PinduoduoAccessTokenResult> getAccessToken(PinduoduoAccessTokenRequest request) {

		// 1、检查serverUrl、appkey、appsert参数是否有空
        if(request == null ||
        		 StringUtils.isEmpty(request.getClientId()) ||
        		 StringUtils.isEmpty(request.getClientSecret()) ||
        		 StringUtils.isEmpty(request.getCode()) ||
        		 StringUtils.isEmpty(request.getGrantType())) {
        	return BaseResponse.error(ErrorCode.INVALID_PARAMS.getCode(),ErrorCode.INVALID_PARAMS.getDesc());
        }

        // 6、发送报文并获取响应的报文串
        String respJson = null;
        try {
            respJson = HttpClientUtil.post(Constants.PINDUODUO_AUTH_URL, JSON.toJSONString(request), false);
        } catch (Exception e) {
            logger.error("Http Post is failed",e);
            return BaseResponse.error(ErrorCode.HTTP_EXCEPTION.getCode(), e.getMessage());
        }

        if(StringUtils.isEmpty(respJson)){
            logger.warn("resp Json is empty");
            return BaseResponse.error(ErrorCode.HTTP_EXCEPTION.getCode(), "resp Json is empty");
        }

        if(JSONObject.parseObject(respJson).containsKey("error_response")){
        	logger.error("respJson has error:"+JSONObject.parseObject(respJson).toString());
            return BaseResponse.error(ErrorCode.HTTP_EXCEPTION.getCode(), "resp has error_response");
        }

        JSONObject jsonObject = JSONObject.parseObject(respJson);

        PinduoduoAccessTokenResult pinduoduoAccessTokenResult = JSONObject.toJavaObject(jsonObject, PinduoduoAccessTokenResult.class);

		return BaseResponse.success(pinduoduoAccessTokenResult);

	}

	@Override
	public BaseResponse<PinduoduoAccessTokenResult> refreshAccessToken(PinduoduoRefreshAccessTokenRequest request) {
		// 1、检查serverUrl、appkey、appsert参数是否有空
        if(request == null ||
        		 StringUtils.isEmpty(request.getClientId()) ||
        		 StringUtils.isEmpty(request.getClientSecret()) ||
        		 StringUtils.isEmpty(request.getRefreshToken()) ||
        		 StringUtils.isEmpty(request.getGrantType())) {
        	return BaseResponse.error(ErrorCode.INVALID_PARAMS.getCode(),ErrorCode.INVALID_PARAMS.getDesc());
        }

        // 6、发送报文并获取响应的报文串
        String respJson = null;
        try {
            respJson = HttpClientUtil.post(Constants.PINDUODUO_AUTH_URL, JSON.toJSONString(request), false);
        } catch (Exception e) {
            logger.error("Http Post is failed",e);
            return BaseResponse.error(ErrorCode.HTTP_EXCEPTION.getCode(), e.getMessage());
        }

        if(StringUtils.isEmpty(respJson)){
            logger.warn("resp Json is empty");
            return BaseResponse.error(ErrorCode.HTTP_EXCEPTION.getCode(), "resp Json is empty");
        }

        if(JSONObject.parseObject(respJson).containsKey("error_response")){
        	logger.error("respJson has error:"+JSONObject.parseObject(respJson).toString());
            return BaseResponse.error(ErrorCode.HTTP_EXCEPTION.getCode(), "resp has error_response");
        }

        JSONObject jsonObject = JSONObject.parseObject(respJson);

        PinduoduoAccessTokenResult pinduoduoAccessTokenResult = (PinduoduoAccessTokenResult) JSONObject.toJavaObject(
        		jsonObject, PinduoduoAccessTokenResult.class);

		return BaseResponse.success(pinduoduoAccessTokenResult);
	}

	@Override
	public boolean checkTokenExpire(PinduoduoOrderIncrementRequest request) {
		BaseResponse<BaseOrderListResult<BaseOrder>> result = execute(request);
		if(!result.isSuccess()) {
			if(Constants.PINDUODUOD_TOKEN_EXPIRED.equals(result.getMsg())) {
				return false;
			}
			logger.error("拼多多请求异常" + result.getMsg());
			throw new MyException(ErrorCode.INTERNAL_SERVER_ERROR.getCode(), "拼多多验证异常");
		}
		return true;
	}

	@Override
	public PinduoduoOrderInfoResult getOrderInfo(PinduoduoOrderInfoRequest request) {
        if(request == null || StringUtils.isEmpty(Constants.PINDUODUO_API_URL)) {
        	return null;
        }

        String clientId = request.getClientId();
	    String type = request.getMethodName();
	    String dataType = "JSON";
	    long timestamp = System.currentTimeMillis() /1000;

        String  orderSn = request.getOrderSn();

        TreeMap<String, Object> requestParamsMap = new TreeMap<String, Object>();

	    requestParamsMap.put("type", type);
		requestParamsMap.put("client_id", clientId);
		requestParamsMap.put("access_token", request.getSessionKey());
	    requestParamsMap.put("timestamp", Long.toString(timestamp));
	    requestParamsMap.put("data_type", dataType);
        requestParamsMap.put("order_sn", orderSn);

        String secret = request.getClientSecret();

		StringBuilder initSign = new StringBuilder(secret);
	    for(Entry<String,Object> param : requestParamsMap.entrySet()){
	    	initSign.append(param.getKey()+param.getValue());
	    }
	    initSign.append(secret);
	    String sign = Md5Util.md5(initSign.toString()).toUpperCase();
	    requestParamsMap.put("sign", sign);

        String respJson = null;
        try {
            respJson = HttpClientUtil.post(Constants.PINDUODUO_API_URL, requestParamsMap);
        } catch (Exception e) {
            logger.error("Http Post is failed",e);
            return null;
        }
        if(StringUtils.isEmpty(respJson)){
            logger.error("resp Json is empty");
            return null;
        }
        if(JSONObject.parseObject(respJson).containsKey("error_response")){
        	logger.error("resp Json has error:"+JSONObject.parseObject(respJson).toString());
            return null;
        }

        JSONObject jsonObject = JSONObject.parseObject(respJson);

        PinduoduoTrade trade = JSONObject.toJavaObject(jsonObject.getJSONObject("order_info_get_response").getJSONObject("order_info"), PinduoduoTrade.class);

		PinduoduoOrderInfoResult result = new PinduoduoOrderInfoResult();
		result.setPinduoduoTrade(trade);

		return result ;
	}

	@Override
	public PinduoduoGoodsListGetResult getGoodList(PinduoduoGoodsListGetRequest request) {
        if(request == null || StringUtils.isEmpty(Constants.PINDUODUO_API_URL)) {
        	return null;
        }

        String clientId = request.getClientId();
	    String type = request.getMethodName();
	    String dataType = "JSON";
	    long timestamp = System.currentTimeMillis() /1000;

        TreeMap<String, Object> requestParamsMap = new TreeMap<String, Object>();

	    requestParamsMap.put("type", type);
		requestParamsMap.put("client_id", clientId);
		requestParamsMap.put("access_token", request.getSessionKey());
	    requestParamsMap.put("timestamp", Long.toString(timestamp));
	    requestParamsMap.put("data_type", dataType);
	    if(StringUtils.isNotEmpty(request.getOuterId())) {
	    	requestParamsMap.put("outer_id", request.getOuterId());
	    }
	    if(StringUtils.isNotEmpty(request.getIsOnsale())) {
	    	requestParamsMap.put("isOnsale", request.getIsOnsale());
	    }
	    if(StringUtils.isNotEmpty(request.getGoodsName())) {
	    	requestParamsMap.put("goodsName", request.getGoodsName());
	    }
	    if(StringUtils.isNotEmpty(request.getPageSize())) {
	    	requestParamsMap.put("pageSize", request.getPageSize());
	    }
	    if(StringUtils.isNotEmpty(request.getPage())) {
	    	requestParamsMap.put("page", request.getPage());
	    }
        String secret = request.getClientSecret();

		StringBuilder initSign = new StringBuilder(secret);
	    for(Entry<String,Object> param : requestParamsMap.entrySet()){
	    	initSign.append(param.getKey()+param.getValue());
	    }
	    initSign.append(secret);
	    String sign = Md5Util.md5(initSign.toString()).toUpperCase();
	    requestParamsMap.put("sign", sign);

        String respJson = null;
        try {
            respJson = HttpClientUtil.post(Constants.PINDUODUO_API_URL, requestParamsMap);
        } catch (Exception e) {
            logger.error("Http Post is failed",e);
            return null;
        }
        if(StringUtils.isEmpty(respJson)){
            logger.error("resp Json is empty");
            return null;
        }
        if(JSONObject.parseObject(respJson).containsKey("error_response")){
        	logger.error("resp Json has error:"+JSONObject.parseObject(respJson).toString());
            return null;
        }

        JSONObject jsonObject = JSONObject.parseObject(respJson);

        PinduoduoGoodsListGet pinduoduoGoodsListGet = JSONObject.toJavaObject(jsonObject.getJSONObject("goods_list_get_response"), PinduoduoGoodsListGet.class);

		PinduoduoGoodsListGetResult result = new PinduoduoGoodsListGetResult();
		result.setPinduoduoGoodsListGet(pinduoduoGoodsListGet);

		return result ;
	}

	@Override
	public String getShopName(String platformMerchantId) {
		if(StringUtils.isEmpty(platformMerchantId)) {
			return null;
		}

		String shopName = null;
		try {
			String respJson = HttpClientUtil.get(SHOP_NAME_BEGIN_URL + platformMerchantId + SHOP_NAME_END_URL);
			JSONObject jsonObject = JSONObject.parseObject(respJson);
			if( jsonObject != null) {
				shopName = jsonObject.getString("mall_name");
			}
		} catch (Exception e) {
            logger.error("getShopName is failed", e);
            return null;
        }
		return shopName;
	}


	@Override
	public PinduoduoDDKGoodsResult getDDKGoodsList(PinduoduoDDKGoodsRequest request) {
		if(request == null || StringUtils.isEmpty(Constants.PINDUODUO_API_URL)) {
        	return null;
        }

        TreeMap<String, Object> requestParamsMap = new TreeMap<String, Object>();
	    requestParamsMap.put("type", request.getMethodName());
	    requestParamsMap.put("timestamp", Long.toString(System.currentTimeMillis() /1000));
		requestParamsMap.put("client_id", request.getClientId());
		if(StringUtils.isNotEmpty(request.getKeyword())) {
			requestParamsMap.put("keyword", request.getKeyword());
		}
  		if(request.getCategoryId() != null) {
  			requestParamsMap.put("category_id", request.getCategoryId());
  		}
		if(request.getPage() != null) {
			requestParamsMap.put("page", request.getPage());
		}
	    if(request.getPageSize() != null ) {
	    	requestParamsMap.put("page_size", request.getPageSize());
	    }
	    if(request.getOptId() != null ) {
	    	requestParamsMap.put("opt_id", request.getOptId());
	    }
	    if(request.getGoodsIdList() != null ) {
	    	requestParamsMap.put("goods_id_list", request.getGoodsIdList());
	    }
	    requestParamsMap.put("sort_type", request.getSortType());
	    requestParamsMap.put("with_coupon", request.isWithCoupon());
	    if(request.getRangeList()!=null){
			requestParamsMap.put("range_list", request.getRangeList());
		}
        String secret = request.getClientSecret();

		StringBuilder initSign = new StringBuilder(secret);
	    for(Entry<String,Object> param : requestParamsMap.entrySet()){
	    	initSign.append(param.getKey()+param.getValue());
	    }
	    initSign.append(secret);
	    String sign = Md5Util.md5(initSign.toString()).toUpperCase();
	    requestParamsMap.put("sign", sign);

        String respJson = null;
        try {
            respJson = HttpClientUtil.post(Constants.PINDUODUO_API_URL, requestParamsMap);
        } catch (Exception e) {
            logger.error("Http Post is failed",e);
            return null;
        }
        if(StringUtils.isEmpty(respJson)){
            logger.error("resp Json is empty");
            return null;
        }
        if(JSONObject.parseObject(respJson).containsKey("error_response")){
        	logger.error("resp Json has error:"+JSONObject.parseObject(respJson).toString());
            return null;
        }

        JSONObject jsonObject = JSONObject.parseObject(respJson);


        PinduoduoDDKGoodsResult result = JSONObject.toJavaObject(
        		jsonObject.getJSONObject("goods_search_response"), PinduoduoDDKGoodsResult.class);
		return result ;
	}

	@Override
	public PinduoduoDDKOrderListIncrementResult getOrderListIncrement(PinduoduoDDKOrderListIncrementRequest request) {
		if(request == null || StringUtils.isEmpty(Constants.PINDUODUO_API_URL)) {
        	return null;
        }
		String dataType = "JSON";
        TreeMap<String, Object> requestParamsMap = new TreeMap<String, Object>();
	    requestParamsMap.put("type", request.getMethodName());
	    requestParamsMap.put("timestamp", Long.toString(System.currentTimeMillis() /1000));
		requestParamsMap.put("client_id", request.getClientId());
		requestParamsMap.put("data_type", dataType);
		if(request.getPage() != null) {
			requestParamsMap.put("page", request.getPage());
		}
	    if(request.getPageSize() != null ) {
	    	requestParamsMap.put("page_size", request.getPageSize());
	    }
	    if(StringUtils.isNotEmpty(request.getpId())) {
	    	requestParamsMap.put("p_id", request.getpId());
	    }

	    requestParamsMap.put("start_update_time", request.getStartUpdateTime());
	    requestParamsMap.put("end_update_time", request.getEndUpdateTime());

        String secret = request.getClientSecret();

		StringBuilder initSign = new StringBuilder(secret);
	    for(Entry<String,Object> param : requestParamsMap.entrySet()){
	    	initSign.append(param.getKey()+param.getValue());
	    }
	    initSign.append(secret);
	    String sign = Md5Util.md5(initSign.toString()).toUpperCase();
	    requestParamsMap.put("sign", sign);

        String respJson = null;
        try {
            respJson = HttpClientUtil.post(Constants.PINDUODUO_API_URL, requestParamsMap);
        } catch (Exception e) {
            logger.error("Http Post is failed",e);
            return null;
        }
        if(StringUtils.isEmpty(respJson)){
            logger.error("resp Json is empty");
            return null;
        }
        if(JSONObject.parseObject(respJson).containsKey("error_response")){
        	logger.error("resp Json has error:"+JSONObject.parseObject(respJson).toString());
            return null;
        }

        JSONObject jsonObject = JSONObject.parseObject(respJson);


        PinduoduoDDKOrderListIncrementResult result = JSONObject.toJavaObject(
        		jsonObject.getJSONObject("order_list_get_response"), PinduoduoDDKOrderListIncrementResult.class);
		return result ;
	}

    @Override
	public PinduoduoDDKGoodsDetailResult getDDKGoodsDetail(PinduoduoDDKGoodsDeatilRequest request){
        if(request == null || StringUtils.isEmpty(Constants.PINDUODUO_API_URL)) {
            return null;
        }
        TreeMap<String, Object> requestParamsMap = new TreeMap<String, Object>();
        requestParamsMap.put("timestamp", Long.toString(System.currentTimeMillis() /1000));
        requestParamsMap.put("type", request.getMethodName());
        requestParamsMap.put("goods_id_list", request.getGoodsIdList());
        requestParamsMap.put("client_id", request.getClientId());
        String secret = request.getClientSecret();
        StringBuilder initSign = new StringBuilder(secret);
        for(Entry<String,Object> param : requestParamsMap.entrySet()){
            initSign.append(param.getKey()+param.getValue());
        }
        initSign.append(secret);
        String sign = Md5Util.md5(initSign.toString()).toUpperCase();
        requestParamsMap.put("sign", sign);
        String respJson = null;
        try {
            respJson = HttpClientUtil.post(Constants.PINDUODUO_API_URL, requestParamsMap);
        } catch (Exception e) {
            logger.error("Http Post is failed",e);
            return null;
        }
        if(StringUtils.isEmpty(respJson)){
            logger.error("resp Json is empty");
            return null;
        }
        if(JSONObject.parseObject(respJson).containsKey("error_response")){
            logger.error("resp Json has error:"+JSONObject.parseObject(respJson).toString());
            return null;
        }
        JSONObject jsonObject = JSONObject.parseObject(respJson);


        PinduoduoDDKGoodsDetailResult result = JSONObject.toJavaObject(
                jsonObject.getJSONObject("goods_detail_response"),  PinduoduoDDKGoodsDetailResult.class);
        return result ;
    }


    @Override
    public PinduoduoGoodsOptGetResult getGoodsOpt(PinduoduoGoodsOptGetRequest request) {
        if(request == null || StringUtils.isEmpty(Constants.PINDUODUO_API_URL)) {
            return null;
        }
        TreeMap<String, Object> requestParamsMap = new TreeMap<String, Object>();
        requestParamsMap.put("timestamp", Long.toString(System.currentTimeMillis() /1000));
        requestParamsMap.put("type", request.getMethodName());
        requestParamsMap.put("parent_opt_id", request.getParentOptId());
        requestParamsMap.put("client_id", request.getClientId());
        String secret = request.getClientSecret();
        StringBuilder initSign = new StringBuilder(secret);
        for(Entry<String,Object> param : requestParamsMap.entrySet()){
            initSign.append(param.getKey()+param.getValue());
        }
        initSign.append(secret);
        String sign = Md5Util.md5(initSign.toString()).toUpperCase();
        requestParamsMap.put("sign", sign);
        String respJson = null;
        try {
            respJson = HttpClientUtil.post(Constants.PINDUODUO_API_URL, requestParamsMap);
        } catch (Exception e) {
            logger.error("Http Post is failed",e);
            return null;
        }
        if(StringUtils.isEmpty(respJson)){
            logger.error("resp Json is empty");
            return null;
        }
        if(JSONObject.parseObject(respJson).containsKey("error_response")){
            logger.error("resp Json has error:"+JSONObject.parseObject(respJson).toString());
            return null;
        }
        JSONObject jsonObject = JSONObject.parseObject(respJson);


        PinduoduoGoodsOptGetResult result = JSONObject.toJavaObject(
                jsonObject.getJSONObject("goods_opt_get_response"),  PinduoduoGoodsOptGetResult.class);
        return result ;
    }

    @Override
    public PinduoduoDDKGoodsPidGenerateResult getPidGenerate(PinduoduoDDKGoodsPIdRequest request) {
        if(request == null || StringUtils.isEmpty(Constants.PINDUODUO_API_URL)) {
            return null;
        }
        TreeMap<String, Object> requestParamsMap = new TreeMap<String, Object>();
        requestParamsMap.put("timestamp", Long.toString(System.currentTimeMillis() /1000));
        requestParamsMap.put("type", request.getMethodName());
        requestParamsMap.put("number", request.getNumber());
        if(StringUtils.isNotEmpty(request.getpIdNameList())) {
        	requestParamsMap.put("p_id_name_list", request.getpIdNameList());
        }
        requestParamsMap.put("client_id", request.getClientId());
        String secret = request.getClientSecret();
        StringBuilder initSign = new StringBuilder(secret);
        for(Entry<String,Object> param : requestParamsMap.entrySet()){
            initSign.append(param.getKey()+param.getValue());
        }
        initSign.append(secret);
        String sign = Md5Util.md5(initSign.toString()).toUpperCase();
        requestParamsMap.put("sign", sign);
        String respJson = null;
        try {
            respJson = HttpClientUtil.post(Constants.PINDUODUO_API_URL, requestParamsMap);
        } catch (Exception e) {
            logger.error("Http Post is failed",e);
            return null;
        }
        if(StringUtils.isEmpty(respJson)){
            logger.error("resp Json is empty");
            return null;
        }
        if(JSONObject.parseObject(respJson).containsKey("error_response")){
            logger.error("resp Json has error:"+JSONObject.parseObject(respJson).toString());
            return null;
        }
        JSONObject jsonObject = JSONObject.parseObject(respJson);


        PinduoduoDDKGoodsPidGenerateResult result = JSONObject.toJavaObject(
                jsonObject.getJSONObject("p_id_generate_response"),PinduoduoDDKGoodsPidGenerateResult.class);
        return result ;
    }

    @Override
    public PinduoduoDDKGoodsPromotionUrlResult getPromotionUrl (PinduoduoDDKGoodsPromotionUrlRequest request) {
        if(request == null || StringUtils.isEmpty(Constants.PINDUODUO_API_URL)) {
            return null;
        }
        TreeMap<String, Object> requestParamsMap = new TreeMap<String, Object>();
        requestParamsMap.put("timestamp", Long.toString(System.currentTimeMillis() /1000));
        requestParamsMap.put("type", request.getMethodName());
        requestParamsMap.put("p_id", request.getpId());
        requestParamsMap.put("goods_id_list", request.getGoodsIdList());
        requestParamsMap.put("generate_short_url", request.isGenerateShortUrl());
        requestParamsMap.put("multi_group", request.getMultiGroup());
        requestParamsMap.put("generate_we_app", request.isGenerateWeApp());
        requestParamsMap.put("client_id", request.getClientId());
        if (StringUtils.isNotBlank(request.getCustomParameters())){
            requestParamsMap.put("custom_parameters", request.getCustomParameters());
        }
        String secret = request.getClientSecret();
        StringBuilder initSign = new StringBuilder(secret);
        for(Entry<String,Object> param : requestParamsMap.entrySet()){
            initSign.append(param.getKey()+param.getValue());
        }
        initSign.append(secret);
        String sign = Md5Util.md5(initSign.toString()).toUpperCase();
        requestParamsMap.put("sign", sign);
        String respJson = null;
        try {
            respJson = HttpClientUtil.post(Constants.PINDUODUO_API_URL, requestParamsMap);
        } catch (Exception e) {
            logger.error("Http Post is failed",e);
            return null;
        }
        if(StringUtils.isEmpty(respJson)){
            logger.error("resp Json is empty");
            return null;
        }
        if(JSONObject.parseObject(respJson).containsKey("error_response")){
            logger.error("resp Json has error:"+JSONObject.parseObject(respJson).toString());
            return null;
        }
        JSONObject jsonObject = JSONObject.parseObject(respJson);


        PinduoduoDDKGoodsPromotionUrlResult result = JSONObject.toJavaObject(
                jsonObject.getJSONObject("goods_promotion_url_generate_response"),  PinduoduoDDKGoodsPromotionUrlResult.class);
        return result ;
    }

    @Override
    public PinduoduoDDKThemeGoodsSearchResult getThemeGoodsSearch(PinduoduoDDKthemeGoodsSearchRequest request) {
        if(request == null || StringUtils.isEmpty(Constants.PINDUODUO_API_URL)) {
            return null;
        }
        TreeMap<String, Object> requestParamsMap = new TreeMap<String, Object>();
        requestParamsMap.put("timestamp", Long.toString(System.currentTimeMillis() /1000));
        requestParamsMap.put("type", request.getMethodName());
        requestParamsMap.put("theme_id", request.getThemeId());
        requestParamsMap.put("client_id", request.getClientId());
        String secret = request.getClientSecret();
        StringBuilder initSign = new StringBuilder(secret);
        for(Entry<String,Object> param : requestParamsMap.entrySet()){
            initSign.append(param.getKey()+param.getValue());
        }
        initSign.append(secret);
        String sign = Md5Util.md5(initSign.toString()).toUpperCase();
        requestParamsMap.put("sign", sign);
        String respJson = null;
        try {
            respJson = HttpClientUtil.post(Constants.PINDUODUO_API_URL, requestParamsMap);
        } catch (Exception e) {
            logger.error("Http Post is failed",e);
            return null;
        }
        if(StringUtils.isEmpty(respJson)){
            logger.error("resp Json is empty");
            return null;
        }
        if(JSONObject.parseObject(respJson).containsKey("error_response")){
            logger.error("resp Json has error:"+JSONObject.parseObject(respJson).toString());
            return null;
        }
        JSONObject jsonObject = JSONObject.parseObject(respJson);


		PinduoduoDDKThemeGoodsSearchResult result = JSONObject.toJavaObject(
                jsonObject.getJSONObject("theme_list_get_response"),  PinduoduoDDKThemeGoodsSearchResult.class);
        return result ;
    }

	@Override
	public PinduoduoDDKMallUrlGenResult getMallUrlGen (PinduoduoDDKMallUrlGenRequest request) {
		if(Objects.isNull(request) || StringUtils.isEmpty(Constants.PINDUODUO_API_URL)) {
			return null;
		}
		Map<String, Object> paramMap = transPinduoduoDDKMallUrlGenRequest2Map(request,new TreeMap<>());
		String secret = request.getClientSecret();

		StringBuilder strSign = new StringBuilder(secret);

		for(String param : paramMap.keySet()){
			strSign.append(param).append(paramMap.get(param));
		}
		strSign.append(secret);

		String sign = Md5Util.md5(strSign.toString()).toUpperCase();
		paramMap.put("sign", sign);
		String respJson;
		try {
			respJson = HttpClientUtil.post(Constants.PINDUODUO_API_URL, paramMap);
		} catch (Exception e) {
			logger.error("Http Post is failed",e);
			return null;
		}
		if(StringUtils.isEmpty(respJson)){
			logger.error("resp Json is empty");
			return null;
		}
		if(JSONObject.parseObject(respJson).containsKey("error_response")){
			logger.error("resp Json has error:"+JSONObject.parseObject(respJson).toString());
			return null;
		}
		JSONObject jsonObject = JSONObject.parseObject(respJson);
		return JSONObject.toJavaObject(jsonObject.getJSONObject("mall_coupon_generate_url_response"),
				PinduoduoDDKMallUrlGenResult.class);
	}

	private static Map<String, Object> transPinduoduoDDKMallUrlGenRequest2Map(PinduoduoDDKMallUrlGenRequest request,
																			  Map<String, Object> paramMap) {
		paramMap.put("client_id",request.getClientId());
		paramMap.put("pid",request.getPid());
		paramMap.put("timestamp",Long.toString(System.currentTimeMillis() /1000));
		paramMap.put("type",request.getType());
		paramMap.put("data_type","JSON");
		paramMap.put("mall_id",request.getMallId());

		if (Objects.nonNull(request.getCouponType())){
			paramMap.put("coupon_type",request.getCouponType());
		}
		if (StringUtils.isNotBlank(request.getCustomParameters())){
			paramMap.put("custom_parameters",request.getCustomParameters());
		}
		if (Objects.nonNull(request.getGenerateShortUrl())){
			paramMap.put("generate_short_url",request.getGenerateShortUrl());
		}
		if (Objects.nonNull(request.getGenerateWeappWebview())){
			paramMap.put("generate_weapp_webview",request.getGenerateWeappWebview());
		}
		if (Objects.nonNull(request.getMultiGroup())){
			paramMap.put("multi_group",request.getMultiGroup());
		}


		return paramMap;

	}

}
